namespace iScadaFBD
{
    using System;
    using System.Drawing;
    using System.Windows.Forms;

    public class ToolPointer : iScadaFBD.Tool
    {
        private FBObject fromFB = null;
        private int fromNode = -1;
        private Point lastPoint = new Point(0, 0);
        private Connection moveConnection = null;
        private int moveLineIndex = -1;
        private DrawObject resizedObject;
        private int resizedObjectHandle;
        private SelectionMode selectMode = SelectionMode.None;
        private Point startPoint = new Point(0, 0);
        private FBObject toFB = null;
        private int toNode = -1;

        public void CheckConnection()
        {
            if (this.fromFB != null)
            {
                OutNodeObject obj2 = (OutNodeObject) this.fromFB.OutNodeList[this.fromNode];
            }
            if (this.toFB != null)
            {
                InNodeObject obj3 = (InNodeObject) this.toFB.InNodeList[this.toNode];
            }
        }

        protected void GetEndNode(DrawArea drawArea, Point point)
        {
            OutNodeObject obj4;
            InNodeObject obj5;
            DrawObject selectedObject = drawArea.ObjList.GetSelectedObject(point);
            if ((selectedObject != null) && (selectedObject.ObjectType == GlobalParam.ObjectType.FunctionBlock))
            {
                FBObject obj3 = (FBObject) drawArea.ObjList.GetSelectedObject(point);
                if (obj3 != null)
                {
                    int num;
                    for (num = 0; num < obj3.OutNodeList.Count; num++)
                    {
                        obj4 = (OutNodeObject) obj3.OutNodeList[num];
                        if (obj4.PointInNode(point))
                        {
                            this.fromFB = obj3;
                            this.fromNode = num;
                            break;
                        }
                    }
                    for (num = 0; num < obj3.InNodeList.Count; num++)
                    {
                        obj5 = (InNodeObject) obj3.InNodeList[num];
                        if (obj5.PointInNode(point))
                        {
                            this.toFB = obj3;
                            this.toNode = num;
                            break;
                        }
                    }
                }
            }
            if ((((this.fromFB != null) && (this.fromNode >= 0)) && (this.toFB != null)) && (this.toNode >= 0))
            {
                obj4 = (OutNodeObject) this.fromFB.OutNodeList[this.fromNode];
                obj5 = (InNodeObject) this.toFB.InNodeList[this.toNode];
                if (obj5.Linked)
                {
                    MessageBox.Show(this.toFB.ObjName + "/" + obj5.NodeName + " 已经被连线!", "Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Hand);
                }
                else
                {
                    obj4.ConnectionCount++;
                    obj4.Linked = true;
                    obj5.Linked = true;
                    Connection connection = new Connection(this.fromFB, this.fromNode, this.toFB, this.toNode, drawArea);
                    this.fromFB.AttachConnections.Add(connection);
                    this.toFB.AttachConnections.Add(connection);
                    drawArea.ObjList.AddObject(connection);
                }
            }
            this.fromFB = null;
            this.toFB = null;
            this.fromNode = -1;
            this.toNode = -1;
        }

        protected Cursor GetMoveLineCursor(DrawArea drawArea, Point point)
        {
            DrawObject selectedObject = drawArea.ObjList.GetSelectedObject(point);
            if ((selectedObject != null) && (selectedObject.ObjectType == GlobalParam.ObjectType.Connection))
            {
                Connection connection = (Connection) drawArea.ObjList.GetSelectedObject(point);
                if (connection.Selected)
                {
                    return connection.GetMoveCursor(point);
                }
            }
            return Cursors.Default;
        }

        protected Rectangle GetNormalizedRectangle(Point startPoint, Point lastPoint)
        {
            int x;
            if (lastPoint.X < startPoint.X)
            {
                x = startPoint.X;
                startPoint.X = lastPoint.X;
                lastPoint.X = x;
            }
            if (lastPoint.Y < startPoint.Y)
            {
                x = startPoint.Y;
                startPoint.Y = lastPoint.Y;
                lastPoint.Y = x;
            }
            return new Rectangle(startPoint.X, startPoint.Y, lastPoint.X - startPoint.X, lastPoint.Y - startPoint.Y);
        }

        protected void GetStartNode(DrawArea drawArea, Point point)
        {
            DrawObject selectedObject = drawArea.ObjList.GetSelectedObject(point);
            if ((selectedObject != null) && (selectedObject.ObjectType == GlobalParam.ObjectType.FunctionBlock))
            {
                FBObject obj3 = (FBObject) drawArea.ObjList.GetSelectedObject(point);
                if (obj3 != null)
                {
                    int num;
                    for (num = 0; num < obj3.OutNodeList.Count; num++)
                    {
                        OutNodeObject obj4 = (OutNodeObject) obj3.OutNodeList[num];
                        if (obj4.PointInNode(point))
                        {
                            this.fromFB = obj3;
                            this.fromNode = num;
                            this.selectMode = SelectionMode.Link;
                            drawArea.StartNodeType = GlobalParam.IO_Type.OUTPUT;
                            drawArea.ConnectStartPoint = obj4.LinkPoint();
                            break;
                        }
                    }
                    for (num = 0; num < obj3.InNodeList.Count; num++)
                    {
                        InNodeObject obj5 = (InNodeObject) obj3.InNodeList[num];
                        if (obj5.PointInNode(point))
                        {
                            this.toFB = obj3;
                            this.toNode = num;
                            this.selectMode = SelectionMode.Link;
                            drawArea.StartNodeType = GlobalParam.IO_Type.INPUT;
                            drawArea.ConnectStartPoint = obj5.LinkPoint();
                            break;
                        }
                    }
                }
            }
        }

        public override void OnMouseDown(DrawArea drawArea, MouseEventArgs e)
        {
            int num2;
            DrawObject selectedObject;
            Point point = new Point(e.X, e.Y);
            point = drawArea.ScalePoint(new Point(e.X, e.Y))[0];
            this.selectMode = SelectionMode.None;
            for (num2 = drawArea.ObjList.SelectionCount - 1; num2 >= 0; num2--)
            {
                selectedObject = drawArea.ObjList.GetSelectedObject(num2);
                int num3 = selectedObject.HitTest(point);
                if (num3 > 0)
                {
                    this.selectMode = SelectionMode.Size;
                    this.resizedObject = selectedObject;
                    this.resizedObjectHandle = num3;
                    drawArea.ObjList.UnselectAll();
                    selectedObject.Selected = true;
                    break;
                }
            }
            if (this.selectMode == SelectionMode.None)
            {
                this.moveConnection = null;
                selectedObject = drawArea.ObjList.GetSelectedObject(point);
                if ((selectedObject != null) && (selectedObject.ObjectType == GlobalParam.ObjectType.Connection))
                {
                    Connection connection = (Connection) drawArea.ObjList.GetSelectedObject(point);
                    if (connection.Selected && (connection.GetSelectedLine(point) != null))
                    {
                        if (connection.GetSelectedLine(point).MovedAble)
                        {
                            this.selectMode = SelectionMode.MoveLine;
                            this.moveConnection = connection;
                            this.moveLineIndex = connection.GetMoveLineIndex(point);
                        }
                        else
                        {
                            this.moveConnection = null;
                            this.moveLineIndex = -1;
                        }
                    }
                }
            }
            if (this.selectMode == SelectionMode.None)
            {
                this.GetStartNode(drawArea, point);
            }
            if (this.selectMode == SelectionMode.None)
            {
                int num4 = drawArea.ObjList.Count();
                selectedObject = null;
                for (num2 = num4 - 1; num2 >= 0; num2--)
                {
                    if (drawArea.ObjList[num2].HitTest(point) == 0)
                    {
                        selectedObject = drawArea.ObjList[num2];
                        break;
                    }
                }
                if (selectedObject != null)
                {
                    this.selectMode = SelectionMode.Move;
                    if (!(((Control.ModifierKeys & Keys.Control) != Keys.None) || selectedObject.Selected))
                    {
                        drawArea.ObjList.UnselectAll();
                    }
                    selectedObject.Selected = true;
                    if (selectedObject.ObjectType == GlobalParam.ObjectType.Connection)
                    {
                        drawArea.Cursor = Cursors.Default;
                    }
                    else
                    {
                        drawArea.Cursor = Cursors.SizeAll;
                    }
                }
            }
            if (this.selectMode == SelectionMode.None)
            {
                if ((Control.ModifierKeys & Keys.Control) == Keys.None)
                {
                    drawArea.ObjList.UnselectAll();
                }
                this.selectMode = SelectionMode.NetSelection;
                drawArea.DrawNetRectangle = true;
            }
            this.lastPoint.X = point.X;
            this.lastPoint.Y = point.Y;
            this.startPoint.X = point.X;
            this.startPoint.Y = point.Y;
            drawArea.Capture = true;
            drawArea.NetRectangle = this.GetNormalizedRectangle(this.startPoint, this.lastPoint);
            drawArea.Refresh();
        }

        public override void OnMouseMove(DrawArea drawArea, MouseEventArgs e)
        {
            int num;
            Point point = new Point(e.X, e.Y);
            point = drawArea.ScalePoint(new Point(e.X, e.Y))[0];
            if (e.Button != MouseButtons.None)
            {
                if (e.Button == MouseButtons.Left)
                {
                    int deltaX = point.X - this.lastPoint.X;
                    int deltaY = point.Y - this.lastPoint.Y;
                    this.lastPoint.X = point.X;
                    this.lastPoint.Y = point.Y;
                    if ((this.selectMode == SelectionMode.Size) && (this.resizedObject != null))
                    {
                        this.resizedObject.MoveHandleTo(point, this.resizedObjectHandle);
                        drawArea.Refresh();
                    }
                    if (this.selectMode == SelectionMode.Move)
                    {
                        for (num = drawArea.ObjList.SelectionCount - 1; num >= 0; num--)
                        {
                            drawArea.ObjList.GetSelectedObject(num).Move(deltaX, deltaY);
                        }
                        DrawObject selectedObject = drawArea.ObjList.GetSelectedObject(point);
                        if ((selectedObject != null) && (selectedObject.ObjectType != GlobalParam.ObjectType.Connection))
                        {
                            drawArea.Cursor = Cursors.SizeAll;
                        }
                        drawArea.Refresh();
                    }
                    if (this.selectMode == SelectionMode.Link)
                    {
                        drawArea.DrawLine = true;
                        if (this.PointInNode(drawArea, point))
                        {
                            drawArea.Cursor = Cursors.Cross;
                        }
                        else
                        {
                            drawArea.Cursor = Cursors.Hand;
                        }
                        drawArea.ConnectEndPoint = new Point(point.X, point.Y);
                        drawArea.Refresh();
                    }
                    if (this.selectMode == SelectionMode.MoveLine)
                    {
                        if (this.moveConnection != null)
                        {
                            this.moveConnection.MoveLine(point, this.moveLineIndex);
                        }
                        drawArea.Refresh();
                    }
                    if (this.selectMode == SelectionMode.NetSelection)
                    {
                        drawArea.NetRectangle = this.GetNormalizedRectangle(this.startPoint, this.lastPoint);
                        drawArea.Refresh();
                    }
                }
            }
            else
            {
                Cursor handleCursor = null;
                for (num = drawArea.ObjList.Count() - 1; num >= 0; num--)
                {
                    int handleNumber = drawArea.ObjList[num].HitTest(point);
                    if (handleNumber > 0)
                    {
                        handleCursor = drawArea.ObjList[num].GetHandleCursor(handleNumber);
                        break;
                    }
                }
                for (num = drawArea.ObjList.Count() - 1; num >= 0; num--)
                {
                    DrawObject obj2 = drawArea.ObjList[num];
                    if (obj2.ObjectType == GlobalParam.ObjectType.Connection)
                    {
                        Connection connection = (Connection) drawArea.ObjList[num];
                        if (connection.Selected)
                        {
                            handleCursor = this.GetMoveLineCursor(drawArea, point);
                        }
                    }
                }
                if (this.PointInNode(drawArea, point))
                {
                    handleCursor = Cursors.Cross;
                }
                if (handleCursor == null)
                {
                    handleCursor = Cursors.Default;
                }
                drawArea.Cursor = handleCursor;
            }
        }

        public override void OnMouseUp(DrawArea drawArea, MouseEventArgs e)
        {
            Point point = new Point(e.X, e.Y);
            point = drawArea.ScalePoint(new Point(e.X, e.Y))[0];
            if (this.selectMode == SelectionMode.Link)
            {
                this.GetEndNode(drawArea, point);
            }
            if (this.selectMode == SelectionMode.NetSelection)
            {
                drawArea.ObjList.SelectInRectangle(drawArea.NetRectangle);
                this.selectMode = SelectionMode.None;
                drawArea.DrawNetRectangle = false;
            }
            if (this.resizedObject != null)
            {
                this.resizedObject.Normalize();
                this.resizedObject = null;
            }
            this.selectMode = SelectionMode.None;
            drawArea.DrawLine = false;
            drawArea.Refresh();
        }

        protected bool PointInNode(DrawArea drawArea, Point point)
        {
            DrawObject selectedObject = drawArea.ObjList.GetSelectedObject(point);
            if (((selectedObject != null) && (selectedObject.ObjectType == GlobalParam.ObjectType.FunctionBlock)) && (selectedObject.ObjectType == GlobalParam.ObjectType.FunctionBlock))
            {
                FBObject obj3 = (FBObject) drawArea.ObjList.GetSelectedObject(point);
                if (obj3 != null)
                {
                    int num;
                    for (num = 0; num < obj3.OutNodeList.Count; num++)
                    {
                        OutNodeObject obj4 = (OutNodeObject) obj3.OutNodeList[num];
                        if (obj4.PointInNode(point))
                        {
                            return true;
                        }
                    }
                    for (num = 0; num < obj3.InNodeList.Count; num++)
                    {
                        InNodeObject obj5 = (InNodeObject) obj3.InNodeList[num];
                        if (obj5.PointInNode(point))
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        private enum SelectionMode
        {
            None,
            NetSelection,
            Move,
            Size,
            Link,
            MoveLine
        }
    }
}

